﻿namespace DataScripter.Excel.Formulas
{
    public class Reference : Formula
	{
		private readonly int _rowDiff;
		private readonly int _colDiff;
		private readonly ICell _cell;
		private readonly string _cellReference;

		public Reference(int rowDiff, int colDiff)
		{
			_rowDiff = rowDiff;
			_colDiff = colDiff;
		}

		public Reference(ICell cell)
		{
			_cell = cell;
		}

		public Reference(ICell cell, int rowDiff, int colDiff)
		{
			_cell = cell;
			_rowDiff = rowDiff;
			_colDiff = colDiff;
		}

		public Reference(string cellReference)
		{
			_cellReference = cellReference;
		}

		#region Overrides of Formula

		public override string Resolve(ICell current)
		{
			if (_cellReference != null)
				return _cellReference;
			return (_cell ?? current).GetDiff(_rowDiff, _colDiff).CellReference;
		}

		#endregion

		public static Reference Above(int i)
		{
			return new Reference(-i, 0);
		}
		public static Reference Left(int i)
		{
			return new Reference(0, -i);
		}
		public static Reference Right(int i)
		{
			return new Reference(0, i);
		}

		public static Reference Above()
		{
			return Above(1);
		}
		public static Reference Left()
		{
			return Left(1);
		}
		public static Reference Right()
		{
			return Right(1);
		}

		public static Reference RightAbove()
		{
			return Relative(-1, 1);
		}
		public static Reference Relative(int rows, int cols)
		{
			return new Reference(rows, cols);
		}

		public static Reference LeftAbove()
		{
			return Relative(-1, -1);
		}
		public static Reference LeftUnder()
		{
			return Relative(1, -1);
		}

		public override string ToString()
		{
			string format = string.Format("({0}, {1})", _rowDiff, _colDiff);
			return _cellReference ?? (_cell == null ? format : _cell.AbsoluteCellReference);
		}
	}
}